package com.dy.yunying.biz.service.usergroup.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dy.yunying.api.entity.GameRole;
import com.dy.yunying.api.entity.WanUser;
import com.dy.yunying.api.entity.usergroup.UserGroup;
import com.dy.yunying.api.entity.usergroup.UserGroupData;
import com.dy.yunying.api.enums.DimensionEnum;
import com.dy.yunying.api.req.usergroup.UserGroupDataReq;
import com.dy.yunying.api.vo.usergroup.UserGroupDataVo;
import com.dy.yunying.biz.dao.ads.usergroup.UserGroupDataMapper;
import com.dy.yunying.biz.dao.ads.usergroup.UserGroupMapper;
import com.dy.yunying.biz.dao.manage.GameRoleMapper;
import com.dy.yunying.biz.dao.manage.WanUserMapper;
import com.dy.yunying.biz.service.usergroup.UserGroupDataService;
import com.pig4cloud.pig.api.util.StringUtils;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
import java.util.stream.Collectors;

@Log4j2
@Service("userGroupDataService")
@RequiredArgsConstructor
public class UserGroupDataServiceImpl extends ServiceImpl<UserGroupDataMapper, UserGroupData> implements UserGroupDataService {

	private final UserGroupDataMapper userGroupDataMapper;

	private final UserGroupMapper userGroupMapper;

	private final WanUserMapper wanUserMapper;

	private final GameRoleMapper gameRoleMapper;


	/** \UFEFF 去掉特殊字符*/
	public static final String UFEFF = "\uFEFF";


	@Override
	public R saveOrUpdateUserGroupData(UserGroupDataVo vo) throws Throwable {
		UserGroupData entity = new UserGroupData();
		try {
			UserGroup userGroup = userGroupMapper.selectById(vo.getGroupId());
			if(userGroup == null){
				return R.failed("请确认用户群组是否存在");
			}
			String msg = checkVo(vo, userGroup);
			if(StringUtils.isNotBlank(msg)){
				return R.failed(msg);
			}
			BeanUtils.copyProperties(vo, entity);

			if(Objects.nonNull(entity.getId())){
				//更新
				entity.setUpdateId(SecurityUtils.getUser().getId().longValue());
				userGroupDataMapper.updateById(entity);
			}else{
				entity.setType(userGroup.getType());
				entity.setDimension(userGroup.getDimension());
				entity.setCreateId(SecurityUtils.getUser().getId().longValue());
				int count = userGroupDataMapper.insert(entity);

				if(count == 1){
					// 更新群组用户数
					UserGroup userGroupNew = new UserGroup();
					userGroupNew.setId(userGroup.getId());
					userGroupNew.setUserNums(userGroup.getUserNums()!=null?(userGroup.getUserNums()+1):0);
					userGroupMapper.updateById(userGroupNew);
				}

			}
		} catch (Throwable t) {
			log.error("新增/更新用户群组失败", t);
			throw new Throwable(t);
		}
		return R.ok(entity);
	}

	@Override
	public R uploadUserGroupData(UserGroupDataReq req) throws Exception{
		UserGroup userGroup = userGroupMapper.selectById(req.getGroupId());
		if(userGroup == null){
			return R.failed("请确认用户群组是否存在");
		}
		final MultipartFile multipartFile = req.getMultipartFile();
		if (null == multipartFile || multipartFile.isEmpty()) {
			return R.failed("请提供正确的导入文件");
		}
		// 获取名称
		String filename = multipartFile.getOriginalFilename();
		// 获取后缀名
		String suffix = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
		if (!"txt".equalsIgnoreCase(suffix)) {
			return R.failed("请上传txt格式的礼包码文件");
		}


		//校验是否重复
		List<UserGroupData> alreadyData = this.list(Wrappers.<UserGroupData>query().lambda().eq(UserGroupData::getGroupId, req.getGroupId()).select(UserGroupData::getGroupData));
		Set<String> alreadyDataSet = alreadyData.stream().map(UserGroupData::getGroupData).collect(Collectors.toSet());
		//String alreadyDataStr = alreadyDataSet.stream().filter(Objects::nonNull).collect(Collectors.joining(","));

		List<UserGroupData> dataList = new ArrayList<>();
		List<String> cfList = new ArrayList<>();
		BufferedReader bufferedReader = null;
		try {
			List<String> dataStrList = new ArrayList<>();
			bufferedReader = new BufferedReader(new InputStreamReader(multipartFile.getInputStream()));
			String lineTxt = null;

			//总条数
			int total = 0;
			List<String> lines = new ArrayList<>();
			while ((lineTxt = bufferedReader.readLine()) != null){
				total++;
				lineTxt = lineTxt.trim();
				//去除UFEFF
				if (StringUtils.isNotBlank(lineTxt) && lineTxt.startsWith(UFEFF)) {
					lineTxt = lineTxt.replace(UFEFF, "");
				}
				//为空
				if(StringUtils.isBlank(lineTxt)){
					log.info("不符合要求：{}", lineTxt);
					lines.add(String.valueOf(total));
					continue;
				}

				//存在重复
				if(alreadyDataSet.contains(lineTxt)){
					log.info("存在重复：{}", lineTxt);
					cfList.add(lineTxt);
					continue;
				}

				dataStrList.add(lineTxt);
			}

			if(total == 0){
				return R.failed("上传内容为空，请检查文件内容");
			}

			if(CollectionUtils.isEmpty(dataStrList)){
				return R.failed("请检查文件内容中的数据是否都为空或者都已存在，请勿重复提交");
			}
			//判断哪些数据不存在
			Integer dimension = userGroup.getDimension();
			Set<String> newDataSet = new LinkedHashSet<>();
			switch (DimensionEnum.getOneByType(dimension)){
				case ACCOUNT:
					List<WanUser> wanUserList = wanUserMapper.selectList(Wrappers.<WanUser>lambdaQuery().select(WanUser::getUserid, WanUser::getUsername).in(WanUser::getUsername, dataStrList));
					Set<String> wanUserSet = wanUserList.stream().map(WanUser::getUsername).collect(Collectors.toSet());
					newDataSet = dataStrList.stream().filter(item -> wanUserSet.contains(item)).collect(Collectors.toSet());
					break;
				case ROLEID:
					List<GameRole> gameRoleList = gameRoleMapper.selectList(Wrappers.<GameRole>lambdaQuery().select(GameRole::getRoleId, GameRole::getRoleName).eq(GameRole::getPgameId, userGroup.getPgameId()).in(GameRole::getRoleId, dataStrList));
					Set<String> gameRoleSet = gameRoleList.stream().map(GameRole::getRoleId).collect(Collectors.toSet());
					newDataSet = dataStrList.stream().filter(item -> gameRoleSet.contains(item)).collect(Collectors.toSet());
					break;
				default:
					return R.failed("用户群组筛选维度错误");
			}

			for(String groupData : newDataSet){
				UserGroupData userGroupData = new UserGroupData();
				userGroupData.setGroupData(groupData);
				userGroupData.setGroupId(req.getGroupId());
				userGroupData.setType(userGroup.getType());
				userGroupData.setDimension(userGroup.getDimension());
				userGroupData.setCreateId(SecurityUtils.getUser().getId().longValue());
				dataList.add(userGroupData);
			}
			this.saveBatch(dataList);
			String lineStr = lines.stream().filter(Objects::nonNull).collect(Collectors.joining(","));
			String msg = "成功" + dataList.size() + "条，已存在" + cfList.size() + "条，记录不存在" + (dataStrList.size() - newDataSet.size()) + "条";

			// 更新群组用户数
			if(userGroup != null){
				UserGroup userGroupNew = new UserGroup();
				userGroupNew.setId(userGroup.getId());
				userGroupNew.setUserNums(userGroup.getUserNums()!=null?(userGroup.getUserNums()+dataList.size()):0);
				userGroupMapper.updateById(userGroupNew);
			}
			return R.ok(null, msg);
		} catch (Throwable t){
			R.failed("解析文件失败");
		} finally {
			if(bufferedReader != null){
				bufferedReader.close();
			}
		}

		return R.ok();
	}

	@Override
	public R delete(Long id) {
		UserGroupData userGroupData = userGroupDataMapper.selectById(id);
		if(userGroupData==null){
			return R.failed("数据不存在");
		}
		int count= userGroupDataMapper.deleteById(id);
		if(count!=1){
			return R.failed("删除失败");
		}
		// 更新群组用户数
		UserGroup userGroup = userGroupMapper.selectById(userGroupData.getGroupId());
		if(userGroup != null){
			UserGroup userGroupNew = new UserGroup();
			userGroupNew.setId(userGroup.getId());
			userGroupNew.setUserNums(userGroup.getUserNums()!=null?(userGroup.getUserNums()-1):0);
			userGroupMapper.updateById(userGroupNew);
		}

		return R.ok();
	}

	@Override
	public R batchDelete(List<String> list) {
		List<UserGroupData> datalist = userGroupDataMapper.selectBatchIds(list);
		if(CollectionUtils.isEmpty(datalist)){
			return R.failed("数据不存在");
		}
		List<Long> removeIds = datalist.stream().map(UserGroupData::getId).collect(Collectors.toList());
		int count = userGroupDataMapper.deleteBatchIds(removeIds);
		if(count!=1){
			return R.failed("删除失败");
		}
		// 更新群组用户数
		UserGroup userGroup = userGroupMapper.selectById(datalist.get(0).getGroupId());
		if(userGroup != null){
			UserGroup userGroupNew = new UserGroup();
			userGroupNew.setId(userGroup.getId());
			userGroupNew.setUserNums(userGroup.getUserNums()!=null?(userGroup.getUserNums()-count):0);
			userGroupMapper.updateById(userGroupNew);
		}
		return R.ok();
	}

	private String checkVo(UserGroupDataVo vo, UserGroup userGroup) {

		//校验群组名称是否会重复
		if (Objects.nonNull(vo.getId())) {
			//更新
			UserGroupData userGroupData = userGroupDataMapper.selectOne(Wrappers.<UserGroupData>query().lambda().eq(UserGroupData::getGroupData, vo.getGroupData()).eq(UserGroupData::getGroupId, vo.getGroupId()).ne(UserGroupData::getId, vo.getId()).last("LIMIT 1"));
			if (userGroupData != null) {
				return "存在重复数据";
			}
		} else {
			//新增
			//本群组不允许重复
			UserGroupData userGroupData = userGroupDataMapper.selectOne(Wrappers.<UserGroupData>query().lambda().eq(UserGroupData::getGroupData, vo.getGroupData()).eq(UserGroupData::getGroupId, vo.getGroupId()).last("LIMIT 1"));
			if (userGroupData != null) {
				return "存在重复数据";
			}
		}
		//增加校验账号和角色是否存在
		Integer dimension = userGroup.getDimension();
		switch (DimensionEnum.getOneByType(dimension)){
			case ACCOUNT:
				WanUser wanUser = wanUserMapper.selectOne(Wrappers.<WanUser>lambdaQuery().select(WanUser::getUserid, WanUser::getUsername).eq(WanUser::getUsername, vo.getGroupData()).last("LIMIT 1"));
				if(wanUser == null){
					return "用户名不存在";
				}
				break;
			case ROLEID:
				GameRole gameRole = gameRoleMapper.selectOne(Wrappers.<GameRole>lambdaQuery().select(GameRole::getRoleId, GameRole::getRoleName).eq(GameRole::getPgameId, userGroup.getPgameId()).eq(GameRole::getRoleId, vo.getGroupData()).last("LIMIT 1"));
				if(gameRole == null){
					return "角色ID不存在";
				}
				break;
			default:
				return "用户群组筛选维度错误";
		}

		return "";
	}


}
